package RadianceM.DistributionSystem.utils;

import RadianceM.DistributionSystem.dto.TokenInfo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @className: TokenUtil
 * @description: Token工具类
 * @author: 小碗
 * @date: 2023-11-04 12:00:33
 */

@Component
public class TokenUtil {

	private final String REDIS_TOKEN_PREFIX = "TOKEN:USERID:";

	public String getRedisTokenPrefix() {
		return REDIS_TOKEN_PREFIX;
	}

	@Resource
	public RedisUtil redisUtil;

	/**
	 * 生成Token
	 * @param userId   键
	 * @param userName 值
	 * @return token 当token==>""说明token生成失败
	 */
	public String generateToken(Long userId, String userName,Long expireTime) {
		String tokenKey = REDIS_TOKEN_PREFIX + userId;
		// 1 判断Redis中Token是否存在
		if(redisUtil.hasKey(tokenKey)) {
			redisUtil.del(tokenKey);
		}
		// 2 生成Token
		TokenInfo tokenInfo = new TokenInfo(
				System.currentTimeMillis(),
				expireTime,
				userId,
				userName
		);
		String token = JwtUtils.createJwtToken(tokenInfo);
		// 3 将token传入redis
		if(!redisUtil.set(tokenKey,token,tokenInfo.getExpireTime(), TimeUnit.HOURS)) {
			return "";
		}
		return token;
	}

	public String generateToken(Long userId, String userName) {
		return generateToken(userId, userName, (long) JwtUtils.getExpireTime());
	}

	/**
	 * 注销token
	 * @param token   token
	 */
	public boolean logoutToken(String token) {
		TokenInfo tokenInfo = JwtUtils.decodeJwtToken(token);
		if(tokenInfo == null) return false; // token有问题 注销失败
		String tokenKey = REDIS_TOKEN_PREFIX + tokenInfo.getUserId();
		if(redisUtil.hasKey(tokenKey)) {
			redisUtil.del(tokenKey);
		}
		return true; // token不在redis中说明过期
	}

	/**
	 * 效验token 通过token
	 * @param token token
	 * @return whether true or false
	 */
	public Boolean verifyToken(String token) {
		TokenInfo tokenInfo = JwtUtils.decodeJwtToken(token);
		// token无效
		if(tokenInfo == null) return false;
		// token过期
//		if(System.currentTimeMillis() > tokenInfo.overtime()) return false;
		// 查询redis token是否存在
		String tokenKey = REDIS_TOKEN_PREFIX + tokenInfo.getUserId();
		String tokenValue = String.valueOf(redisUtil.get(tokenKey));
		if(tokenValue == null) return false;
		// 查询token值是否相等
		return tokenValue.equals(token);
	}

	/**
	 * 刷新token
	 * @param token token
	 * @return      whether true or false
	 */
	public boolean refreshToken(String token) {
		TokenInfo tokenInfo = JwtUtils.decodeJwtToken(token);
		if(tokenInfo == null) return false;
		String tokenKey = REDIS_TOKEN_PREFIX + tokenInfo.getUserId();
		// token不存在，刷新失败
		if(!redisUtil.hasKey(tokenKey)) return false;
		// token存在，更新过期时间
		return redisUtil.set(tokenKey, token, tokenInfo.getExpireTime(), TimeUnit.HOURS);
	}

	/**
	 * 获取剩余时间
	 * @param token token
	 * @return      whether true or false
	 */
	public Long getExpireTime(String token) {
		TokenInfo tokenInfo = JwtUtils.decodeJwtToken(token);
		assert tokenInfo != null;
		String tokenKey = REDIS_TOKEN_PREFIX + tokenInfo.getUserId();
		return redisUtil.getExpire(tokenKey, TimeUnit.SECONDS);
	}

	// 获取token 用户id
	public Long getTokenUserId(String token) {
		return Objects.requireNonNull(JwtUtils.decodeJwtToken(token)).getUserId();
	}

}
